import queue
import random
import time
import threading


class ProducerConsumer:
    def __init__(self, max_size=5):
        self.queue = queue.Queue(maxsize=max_size)
        self.lock = threading.Lock()
        self.producer_done = False

    def producer(self, producer_id):
        for i in range(10):
            item = f"item_{producer_id}_{i}"
            time.sleep(random.uniform(0.1, 0.5))  # 模拟生产时间
            with self.lock:
                if self.queue.full():
                    print(f"Producer {producer_id}: Queue full, waiting...")
                self.queue.put(item)
                print(f"Producer {producer_id}: Produced {item}")

    def consumer(self, consumer_id):
        while True:
            with self.lock:
                if self.queue.empty() and self.producer_done:
                    break
                if self.queue.empty():
                    print(f"Consumer {consumer_id}: Queue empty, waiting...")
                    continue
                item = self.queue.get()
                print(f"Consumer {consumer_id}: Consumed {item}")
                time.sleep(random.uniform(0.2, 0.7))  # 模拟消费时间


# 使用示例
pc = ProducerConsumer()

# 创建生产者线程
producers = []
for i in range(3):
    t = threading.Thread(target=pc.producer, args=(i,))
    producers.append(t)
    t.start()

# 创建消费者线程
consumers = []
for i in range(2):
    t = threading.Thread(target=pc.consumer, args=(i,))
    consumers.append(t)
    t.start()

# 等待生产者完成
for t in producers:
    t.join()

# 通知消费者生产者已完成
pc.producer_done = True

# 等待消费者完成
for t in consumers:
    t.join()

print("All tasks completed")